package commands

import (
	"errors"
	"fmt"
	"io/ioutil"
	"os"
	"path/filepath"
	"strconv"
	"time"

	"github.com/larspensjo/config"
	"github.com/urfave/cli"

	"../flags"
	"../utils"
)

// Init - init action
func Init(config utils.Config) cli.Command {
	return cli.Command{
		Name: "init",
		Aliases: []string{
			"update",
		},
		Usage:    "Init the project or update the project to new version",
		Category: "COMMON COMMANDS",
		Flags: []cli.Flag{
			flags.Flags["path"],
			/*flags.Flags["local"],*/
			cli.StringFlag{
				Name:  "ver",
				Value: "0.0.1",
				Usage: "The new version like x.y.z",
			},
			cli.StringFlag{
				Name:  "master",
				Value: "master",
				Usage: "The name for master branch",
			},
			cli.StringFlag{
				Name:  "develop, dev",
				Value: "dev",
				Usage: "The name for develop branch",
			},
			cli.StringFlag{
				Name:  "beta",
				Value: "BETA",
				Usage: "The name for BETA tag",
			},
		},
		Action: makeAction(config, initAction),
	}
}

func initAction(config utils.Config, git utils.Git, context *cli.Context) error {
	var err error
	fmt.Println("[init start]")

	/*
		if !utils.IsExist(git.Git) {
			file := filepath.Join(config.BasePath, "README.md")
			if !utils.IsExist(file) {
				_, err := os.Create(file)
				if err != nil {
					fmt.Println(err)
					return err
				}
			}
			_, err = git.Execute(
				[]string{"init"},
				[]string{"add", "."},
				[]string{"commit", "-m", "init"},
			)
			if err != nil {
				return err
			}
		}
	*/

	_, err = git.Execute(
		[]string{"pull", "--all"},
	)
	if err != nil {
		return err
	}

	var branches []string
	branches, err = git.Branches()
	if err != nil {
		return err
	}
	var master = context.String("master")
	var hasMaster = false
	var dev = context.String("dev")
	var hasDev = false
	var sgbmConfig = "sgbm-config"
	var hasSgbmConfig = false
	for _, v := range branches {
		if v == master {
			hasMaster = true
		}
		if v == dev {
			hasDev = true
		}
		if v == sgbmConfig {
			hasSgbmConfig = true
		}
	}

	if !(hasSgbmConfig) {
		_, err = git.Execute(
			[]string{"branch", sgbmConfig},
			/* []string{"branch", "--set-upstream-to=origin/sgbm-config", "sgbm-config"}, */
			[]string{"checkout", sgbmConfig},
		)
		if err != nil {
			return err
		}
		var list []os.FileInfo
		list, err = ioutil.ReadDir(config.BasePath)
		if err != nil {
			return err
		}
		for _, item := range list {
			if ".git" != item.Name() {
				os.RemoveAll(filepath.Join(config.BasePath, item.Name()))
			}
		}
	}
	err = initSGBM(config, git, context)
	if err != nil {
		return err
	}

	if !hasMaster {
		_, err = git.Execute(
			[]string{"branch", master},
		)
		if err != nil {
			return err
		}
	}
	if !hasDev {
		_, err = git.Execute(
			[]string{"checkout", master},
			[]string{"branch", dev},
		)
		if err != nil {
			return err
		}
	}

	_, err = git.Execute(
		[]string{"checkout", dev},
	)

	_, err = git.Execute(
		[]string{"push", "-u", "origin", "--all"},
		[]string{"push", "-u", "origin", "--tags"},
	)
	if err != nil {
		return err
	}

	fmt.Println("[init finish]")
	return nil
}

func initSGBM(conf utils.Config, git utils.Git, context *cli.Context) error {
	fmt.Println("[init .sgbm start]")

	var ver = context.String("ver")
	var master = context.String("master")
	var dev = context.String("dev")
	var beta = context.String("beta")

	result, err := utils.LoadConfig(conf, git, "config")
	if err != nil {
		fmt.Println("err != nil")
		utils.SaveConfig(conf, git, "config", func(c *config.Config) *config.Config {
			// 这里是当前版本
			c.AddOption("global", "ver", ver)
			c.AddOption("global", "master", master)
			c.AddOption("global", "dev", dev)
			c.AddOption("global", "beta", beta)

			// user - name - role
			c.AddOption("user", "master", "master")
			return c
		})
	} else {
		fmt.Println("err == nil")
		info, err := result.String("session", conf.PcCode)
		if err != nil {
			return errors.New("The Project based in sgbm, please login to reInit")
		}
		info, err = result.String("user", info)
		if (err != nil) || ("master" != info) {
			return errors.New("The Project based in sgbm, please login with master to reInit")
		}
		err = utils.AddConfig(conf, git, "config", func(c *config.Config) *config.Config {
			c.AddOption("global", "ver", ver)
			c.AddOption("global", "master", master)
			c.AddOption("global", "dev", dev)
			c.AddOption("global", "beta", beta)
			return c
		})
	}

	err = utils.SaveConfig(conf, git, "log", func(c *config.Config) *config.Config {
		time := time.Now().Unix()
		c.AddOption("common", "create_time", strconv.FormatInt(time, 10))
		c.AddOption("common", "num", "0")
		return c
	})

	fmt.Println("[init .sgbm finish]")
	return err
}
